/*
 * ImagenesDAO.java
 *
 * Created on 26 de septiembre de 2006, 17:13
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

package com.src.computec.radarplus.gestionimagenes.dao;
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.SCHEMA;
//
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.MAX_IMAGESTOCOPY;
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.MAX_TRIES_TO_COPY;
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.DAYS_LEFT;
//
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.ENTREGA_BAJOPUERTA_SQL;
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.ENTREGA_BAJOPUERTA_DB2;
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.ENTREGA_NORMAL_DB2;
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.DISTRIBUCION_DB2;
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.GESTIONES_DEVOLUCION_DB2;
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.GESTIONES_ESPECIALES_DB2;
//
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.STATE_SUCCESS_COPY;
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.STATE_TO_COPY;
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.STATE_NOT_IN_RADAR;
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.STATE_INCONSISTENCIA_ESPECIAL;
//
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.PATH_ORIGEN;
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.PATH_DESTINO;
//
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.SEPARATOR;
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.EXTENSION;
//
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.RANGE_IMAGES_BETWEEN;
//
import static com.src.computec.radarplus.gestionimagenes.base.constantes.ConstantesGenerales.CODIGO_GESTION_REENVIO;
//
import com.src.computec.radarplus.gestionimagenes.dto.GestionImagenesDto;
import com.src.computec.radarplus.gestionimagenes.dto.ImagenDto;
import com.src.computec.radarplus.gestionimagenes.exception.CopiaImagenException;
import com.src.computec.radar.base.dao.GenericDAO;
import com.src.computec.radar.base.dao.exception.DAOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;


/**
 *
 * @author Jose Luis Perea Alvarez
 */
public class ImagenesPlusDAO extends GenericDAO implements BaseImagenesPlusDAO
{    
    /** Creates a new instance of ImagenesDAO */
    public ImagenesPlusDAO() {
    }
    
    public List getImagesToCopy() throws DAOException 
    {
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        List retornoLst = new ArrayList();
        
        try 
        {
            con = getConnectionSqlServer();  
                        
            statement = con.prepareStatement("SELECT TOP "+ MAX_IMAGESTOCOPY +" ID, NombreArchivo, CodigoBarras, Ruta, FechaGestion, CodigoGestion, Estado, FechaProceso, FechaArribo, MarcaVerify, Usuario, FechaManual, NumeroCargues " +
                                             "FROM Guias " +
                                             "WHERE FechaProceso > ? AND (Estado = ? OR Estado = ?) AND (NumeroCargues < ? OR NumeroCargues IS NULL) " +
                                             "ORDER BY ID ASC");      
            
            Calendar calendarToday = Calendar.getInstance();
            calendarToday.add(Calendar.DAY_OF_YEAR, -Integer.parseInt(DAYS_LEFT));
            
            int indice = 0;
            statement.setObject(++indice, new Timestamp( calendarToday.getTimeInMillis() ) );
            statement.setObject(++indice, STATE_TO_COPY);
            statement.setObject(++indice, STATE_NOT_IN_RADAR);
            statement.setObject(++indice, MAX_TRIES_TO_COPY);            
            rs = statement.executeQuery();
            
            while(rs.next()) 
            {
                int indice1 = 0;
                ImagenDto dto = new ImagenDto();     
                dto.setConsecutivo(rs.getString(++indice1));
                dto.setNombreArchivo(rs.getString(++indice1));
                dto.setCodigoBarras(rs.getString(++indice1).trim());
                dto.setRuta(rs.getString(++indice1));
                dto.setFechaGestion( rs.getDate(++indice1)); 
                dto.setCodigoGestion( (rs.getString(++indice1) != null && rs.getString(indice1).equals(ENTREGA_BAJOPUERTA_SQL))? ENTREGA_BAJOPUERTA_DB2: ENTREGA_NORMAL_DB2  );
                dto.setEstado(rs.getString(++indice1));         
                dto.setFechaProceso( rs.getDate(++indice1) != null ? rs.getDate(indice1): new Date( (new java.util.Date()).getTime() )); 
                dto.setFechaArribo( rs.getDate(++indice1)); 
                dto.setMarcaVerify(rs.getString(++indice1));
                dto.setUsuario(rs.getString(++indice1));    
                dto.setFechaManual( rs.getDate(++indice1));                        
                dto.setNumeroCargues( rs.getString(++indice1) != null ? rs.getInt(indice1): 0 );
                
                retornoLst.add(dto);
            }
        }
        catch (SQLException e) 
        {
            throw new DAOException("ImagenesPlusDAO: getImagesToCopy: " + e.toString(), e);
        }
        catch (Exception e) 
        {
            throw new DAOException("ImagenesPlusDAO: getImagesToCopy: " + e.toString(), e);
        }
        finally 
        {
            closeConnection(con, statement, rs);
        }
        return retornoLst;
    }   
    
    public List getLastImagesToCopy() throws DAOException 
    {
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        PreparedStatement statement2 = null;
        ResultSet rs2 = null;
        List retornoLst = new ArrayList();
        
        int numeroACargar = 0;
        
        try 
        {
            con = getConnectionSqlServer();  
                        
            statement = con.prepareStatement("SELECT TOP "+ MAX_IMAGESTOCOPY +" ID, NombreArchivo, CodigoBarras, Ruta, FechaGestion, CodigoGestion, Estado, FechaProceso, FechaArribo, MarcaVerify, Usuario, FechaManual, NumeroCargues " +
                                             "FROM Guias " +
                                             "WHERE FechaProceso > ? AND (Estado = ? OR Estado = ?) AND (NumeroCargues < ? OR NumeroCargues IS NULL) " +
                                             "ORDER BY ID DESC");            
            
            statement2 = con.prepareStatement("SELECT COUNT(*) " +
                                             "FROM Guias " +
                                             "WHERE FechaProceso > ? AND (Estado = ? OR Estado = ?) AND (NumeroCargues < ? OR NumeroCargues IS NULL) ");       
            
            Calendar calendarToday = Calendar.getInstance();
            calendarToday.add(Calendar.DAY_OF_YEAR, -Integer.parseInt(DAYS_LEFT));
            
            int indice = 0;
            statement2.setObject(++indice, new Timestamp( calendarToday.getTimeInMillis() ) );
            statement2.setObject(++indice, STATE_TO_COPY);
            statement2.setObject(++indice, STATE_NOT_IN_RADAR);
            statement2.setObject(++indice, MAX_TRIES_TO_COPY);            
            rs2 = statement2.executeQuery();
                
            if(rs2.next())
            {
                int indice1 = 0;
                numeroACargar = rs2.getInt(++indice1);
            }
            
            if(numeroACargar >= RANGE_IMAGES_BETWEEN)
            {            
                indice = 0;
                statement.setObject(++indice, new Timestamp( calendarToday.getTimeInMillis() ) );
                statement.setObject(++indice, STATE_TO_COPY);
                statement.setObject(++indice, STATE_NOT_IN_RADAR);
                statement.setObject(++indice, MAX_TRIES_TO_COPY);            
                rs = statement.executeQuery();

                while(rs.next()) 
                {
                    int indice1 = 0;
                    ImagenDto dto = new ImagenDto();                
                    
                    dto.setConsecutivo(rs.getString(++indice1));
                    dto.setNombreArchivo(rs.getString(++indice1));
                    dto.setCodigoBarras(rs.getString(++indice1).trim());
                    dto.setRuta(rs.getString(++indice1));
                    dto.setFechaGestion( rs.getDate(++indice1)); 
                    dto.setCodigoGestion( (rs.getString(++indice1) != null && rs.getString(indice1).equals(ENTREGA_BAJOPUERTA_SQL))? ENTREGA_BAJOPUERTA_DB2: ENTREGA_NORMAL_DB2  );
                    dto.setEstado(rs.getString(++indice1));         
                    dto.setFechaProceso( rs.getDate(++indice1) != null ? rs.getDate(indice1): new Date( (new java.util.Date()).getTime() )); 
                    dto.setFechaArribo( rs.getDate(++indice1)); 
                    dto.setMarcaVerify(rs.getString(++indice1));
                    dto.setUsuario(rs.getString(++indice1));    
                    dto.setFechaManual( rs.getDate(++indice1));                        
                    dto.setNumeroCargues( rs.getString(++indice1) != null ? rs.getInt(indice1): 0 );

                    retornoLst.add(dto);
                }
            }
        }
        catch (SQLException e) 
        {
            throw new DAOException("ImagenesPlusDAO: getLastImagesToCopy: " + e.toString(), e);
        }
        catch (Exception e) 
        {
            throw new DAOException("ImagenesPlusDAO: getLastImagesToCopy: " + e.toString(), e);
        }
        finally 
        {
            closeConnection(statement2, rs2);
            closeConnection(con, statement, rs);
        }
        return retornoLst;
    }
    
    public void procesarBloqueImagenes(List bloqueImagenes, String fromThread) throws DAOException
    {
        //System.out.println("--------------------------------------------------");
        System.out.println("Gestion Imagenes Plus Inicio: " + fromThread + ": " + new java.util.Date());
        //2. Consulta los registros en db2 si existe envio para esos Codigos de Barra
        GestionImagenesDto gestionImagenesDto = encontrarRegistroEnvios(bloqueImagenes);
        //3. Actualizar los registros sin envio y aumentar intentos de cargue
        registrarGuiasSinEnvio(gestionImagenesDto.getImagenesSinEnvio());
        //4. Actualizar los registros sin imagen, cambiar Estado a no imagen encontrada y aumentar intentos de cargue
        registrarEnviosSinImagen(gestionImagenesDto.getImagenesNoExisten()); 
        //5. Actualizar los registros que tuvieron inconsistencia por distribucion especial, cambiar Estado a inconsistencia de envios especiales y aumentar intentos de cargue
        registrarEnviosInconsistenciaEspecial(gestionImagenesDto.getEnviosInconsistenciasEspeciales()); 
        //6. Copiar Imagenes para imagenes con Envio
        actualizarInfoEnvios(gestionImagenesDto.getImagenesConEnvio()); 
        System.out.println("Gestion Imagenes Plus Fin: " + fromThread + ": " + new java.util.Date());
        //System.out.println("--------------------------------------------------");
    }    
    
    protected GestionImagenesDto encontrarRegistroEnvios(List imagenesLst) throws DAOException
    {
        GestionImagenesDto gestionImagenesDto = new GestionImagenesDto();
        List imagenesConEnvio = new ArrayList();
        List imagenesSinEnvio = new ArrayList();
        List imagenesNoExisten = new ArrayList();
        List enviosInconsistenciasEspeciales = new ArrayList();
        
        if(!imagenesLst.isEmpty())
        {
            Connection con = null;
            PreparedStatement statement = null;
            ResultSet rs = null;
            try 
            {
                con = getConnectionDB2XA();    

                statement = con.prepareStatement("SELECT CODIGO_ULTIMA_GESTION FROM "+ SCHEMA +".ENVIO WHERE CODIGO_BARRAS = ? ");

                Iterator iterator = imagenesLst.iterator();

                while(iterator.hasNext()) 
                {
                    try
                    {
                        ImagenDto dto = (ImagenDto)iterator.next();

                        int indice = 0;                
                        statement.setObject(++indice, dto.getCodigoBarras());                
                        rs = statement.executeQuery();                
                        if(rs.next())
                        {
                            int indice1 = 0; 

                            String codigoUltimaGestion = rs.getString(++indice1) != null? rs.getString(indice1): DISTRIBUCION_DB2;

                            dto.setCodigoUltimaGestion(codigoUltimaGestion);
                            dto.setExisteEnvio(true);

                            if( existeImagenEnEnvio(dto) )
                            {
                                if( !GESTIONES_ESPECIALES_DB2.contains(codigoUltimaGestion) )
                                {
                                    imagenesConEnvio.add(dto);
                                }
                                else
                                {
                                    enviosInconsistenciasEspeciales.add(dto);
                                }
                            }
                            else
                            {
                                dto.setExisteImagen(false);
                                imagenesNoExisten.add(dto);
                            }                        
                        } 
                        else
                        {
                            imagenesSinEnvio.add(dto);
                        }
                    }
                    catch(SQLException e)
                    {
                        System.out.println("ImagenesPlusDAO: encontrarRegistroEnvios: " + e.toString());
                        e.printStackTrace();
                    }
                    catch(Exception e)
                    {
                        System.out.println("ImagenesPlusDAO: encontrarRegistroEnvios: " + e.toString());
                        e.printStackTrace();
                    }
                }           
            }
            catch (SQLException e) 
            {
                throw new DAOException("ImagenesPlusDAO: encontrarRegistroEnvios: " + e.toString(), e);
            }
            catch (Exception e) 
            {
                throw new DAOException("ImagenesPlusDAO: encontrarRegistroEnvios: " + e.toString(), e);
            }
            finally 
            {            
                closeConnection(con, statement, rs);             
            }
        }
        
        gestionImagenesDto.setImagenesConEnvio(imagenesConEnvio);
        gestionImagenesDto.setImagenesSinEnvio(imagenesSinEnvio);
        gestionImagenesDto.setImagenesNoExisten(imagenesNoExisten);
        gestionImagenesDto.setEnviosInconsistenciasEspeciales(enviosInconsistenciasEspeciales);
                
        return gestionImagenesDto;
    }
    
    protected void registrarGuiasSinEnvio(List imagenesSinEnvio) throws DAOException
    {
        if(!imagenesSinEnvio.isEmpty())
        {
            Connection con = null;
            PreparedStatement statement = null;

            try 
            {
                con = getConnectionSqlServer(); 
                con.setAutoCommit(true);

                statement = con.prepareStatement("UPDATE Guias SET Estado = ?, NumeroCargues = ? WHERE ID = ? ");
                
                Iterator iterator = imagenesSinEnvio.iterator();

                while(iterator.hasNext()) 
                {
                    try 
                    {
                        ImagenDto dto = (ImagenDto)iterator.next();

                        int indice = 0;        
                        statement.setObject(++indice, STATE_NOT_IN_RADAR);
                        statement.setObject(++indice, dto.getNumeroCargues() + 1);  
                        statement.setObject(++indice, dto.getConsecutivo());   
                        statement.executeUpdate();
                    }
                    catch (SQLException e) 
                    {
                        System.out.println("ImagenesPlusDAO: registrarGuiasSinEnvio: " + e.toString());
                        e.printStackTrace();
                    }
                    catch (Exception e) 
                    {
                        System.out.println("ImagenesPlusDAO: registrarGuiasSinEnvio: " + e.toString());
                        e.printStackTrace();
                    }
                }
            }
            catch (SQLException e) 
            {
                throw new DAOException("ImagenesPlusDAO: registrarGuiasSinEnvio: " + e.toString(), e);
            }
            catch (Exception e) 
            {
                throw new DAOException("ImagenesPlusDAO: registrarGuiasSinEnvio: " + e.toString(), e);
            }
            finally 
            {
                closeConnection(con, statement);
            }
        }
    }
    
    protected void registrarEnviosSinImagen(List imagenesNoExisten) throws DAOException
    {
        if(!imagenesNoExisten.isEmpty())
        {
            Connection con = null;
            PreparedStatement statement = null;

            try 
            {
                con = getConnectionSqlServer();  
                con.setAutoCommit(true);

                statement = con.prepareStatement("UPDATE Guias SET NumeroCargues = ? WHERE ID = ? ");
                
                Iterator iterator = imagenesNoExisten.iterator();

                while(iterator.hasNext()) 
                {
                    try
                    {
                        ImagenDto dto = (ImagenDto)iterator.next();

                        int indice = 0;          
                        statement.setObject(++indice, dto.getNumeroCargues() + 1);  
                        statement.setObject(++indice, dto.getConsecutivo());   
                        statement.executeUpdate();  
                    }
                    catch (SQLException e) 
                    {
                        System.out.println("ImagenesPlusDAO: registrarEnviosSinImagen: " + e.toString());
                        e.printStackTrace();
                    }
                    catch (Exception e) 
                    {
                        System.out.println("ImagenesPlusDAO: registrarEnviosSinImagen: " + e.toString());
                        e.printStackTrace();
                    }
                }
            }
            catch (SQLException e) 
            {
                throw new DAOException("ImagenesPlusDAO: registrarEnviosSinImagen: " + e.toString(), e);
            }
            catch (Exception e) 
            {
                throw new DAOException("ImagenesPlusDAO: registrarEnviosSinImagen: " + e.toString(), e);
            }
            finally 
            {
                closeConnection(con, statement);
            }
        }
    }
    
    protected void registrarEnviosInconsistenciaEspecial(List imagenesInconsistenciaEspecial) throws DAOException
    {
        if(!imagenesInconsistenciaEspecial.isEmpty())
        {
            Connection conSQL = null;
            Connection conDB2 = null;
            
            PreparedStatement statementSQL = null;            
            PreparedStatement statementDB2UpdateEnvio = null;

            try 
            {
                conSQL = getConnectionSqlServer();  
                conSQL.setAutoCommit(true);

                conDB2 = getConnectionDB2XA();  
                conDB2.setAutoCommit(true);

                statementSQL            = conSQL.prepareStatement("UPDATE Guias SET Estado = ?, FechaRadar = ? WHERE ID = ? ");
                statementDB2UpdateEnvio = conDB2.prepareStatement("UPDATE "+ SCHEMA +".ENVIO SET PATH_IMAGEN = ? WHERE CODIGO_BARRAS = ? ");
                
                java.sql.Timestamp timestampAtMoment = new java.sql.Timestamp((new java.util.Date()).getTime());
                
                Iterator iterator = imagenesInconsistenciaEspecial.iterator();

                while(iterator.hasNext()) 
                {
                    ImagenDto dto = (ImagenDto)iterator.next();
                
                    try
                    {
                        String rutaNueva = copiarImagenGuia(dto);                    

                        if(rutaNueva != null)
                        {                           
                            try
                            {
                                int indice = 0;      
                                statementDB2UpdateEnvio.setObject(++indice, rutaNueva);
                                statementDB2UpdateEnvio.setObject(++indice, dto.getCodigoBarras());
                                statementDB2UpdateEnvio.executeUpdate();

                                indice = 0;  
                                statementSQL.setObject(++indice, STATE_INCONSISTENCIA_ESPECIAL);
                                statementSQL.setObject(++indice, timestampAtMoment);
                                statementSQL.setObject(++indice, dto.getConsecutivo());   
                                statementSQL.executeUpdate(); 
                            }
                            catch (SQLException e) 
                            {
                                System.out.println("ImagenesPlusDAO: registrarEnviosInconsistenciaEspecial: " + e.toString());
                                e.printStackTrace();
                            }
                            catch (Exception e) 
                            {
                                System.out.println("ImagenesPlusDAO: registrarEnviosInconsistenciaEspecial: " + e.toString());
                                e.printStackTrace();
                            }
                        }
                    }
                    catch(CopiaImagenException ciex)
                    {
                        ciex.printStackTrace();
                    }
                }
            }
            catch (SQLException e) 
            {
                throw new DAOException("ImagenesDAO: registrarEnviosInconsistenciaEspecial: " + e.toString(), e);
            }
            catch (Exception e) 
            {
                throw new DAOException("ImagenesDAO: registrarEnviosInconsistenciaEspecial: " + e.toString(), e);
            }
            finally 
            {
                closeConnection(conDB2, statementDB2UpdateEnvio);                
                closeConnection(conSQL, statementSQL);
            }
        }
    }
    
    protected boolean existeImagenEnEnvio(ImagenDto dto)
    {
        File file = new File(PATH_ORIGEN + dto.getRuta());
        if (file.exists()) 
        {
            return true;
        }
        return false;
    }
    
    protected void actualizarInfoEnvios(List imagenesConEnvio) throws DAOException
    {
        if(!imagenesConEnvio.isEmpty())
        {
            Connection conSQL = null;
            Connection conDB2 = null;

            PreparedStatement statementSQL = null;
            
            PreparedStatement statementDB2UpdateEnvio = null;
            PreparedStatement statementDB2UpdateEnvioFecha = null;
            PreparedStatement statementDB2InsertEnvioMovimiento = null;
            PreparedStatement statementDB2InsertEnvioMovimientoSinFechaGestion = null;
            PreparedStatement statementDB2UpdateEnvioMovimiento = null;
            PreparedStatement statementDB2UpdateEnvioMovimientoSinFechaGestion = null;
            
            PreparedStatement stmtUpdateReenvio = null;

            try 
            {
                java.sql.Date dateAtMoment = new java.sql.Date((new java.util.Date()).getTime());
                java.sql.Timestamp timestampAtMoment = new java.sql.Timestamp((new java.util.Date()).getTime());
                
                conSQL = getConnectionSqlServer();  
                conSQL.setAutoCommit(true);

                conDB2 = getConnectionDB2XA();  
                conDB2.setAutoCommit(true);

                statementSQL = conSQL.prepareStatement("UPDATE Guias SET Estado = ?, FechaRadar = ? WHERE ID = ? ");
                
                statementDB2UpdateEnvio             = conDB2.prepareStatement("UPDATE "+ SCHEMA +".ENVIO SET CODIGO_ULTIMA_GESTION = ?, PATH_IMAGEN = ?, FECHA_ULTIMA_GESTION = ? WHERE CODIGO_BARRAS = ? ");
                
                statementDB2UpdateEnvioFecha     = conDB2.prepareStatement("UPDATE "+ SCHEMA +".ENVIO SET FECHA_ULTIMA_GESTION = ? WHERE CODIGO_BARRAS = ? ");
                
                
                statementDB2InsertEnvioMovimiento   = conDB2.prepareStatement("INSERT INTO "+ SCHEMA +".ENVIO_MOVIMIENTO (CODIGO_BARRAS,CODIGO_GESTION,FECHA_MOVIMIENTO,FECHA_IMAGEN,FECHA_CARGA_IMAGEN,CODIGO_RESPONSABLE) VALUES (?,?,?,?,?,'IMAGENES_DIGITALIZACION') ");
                statementDB2InsertEnvioMovimientoSinFechaGestion = conDB2.prepareStatement("INSERT INTO "+ SCHEMA +".ENVIO_MOVIMIENTO (CODIGO_BARRAS,CODIGO_GESTION,FECHA_MOVIMIENTO,FECHA_CARGA_IMAGEN,CODIGO_RESPONSABLE) VALUES (?,?,?,?,'IMAGENES_DIGITALIZACION') ");
                
                statementDB2UpdateEnvioMovimiento   = conDB2.prepareStatement("UPDATE "+ SCHEMA +".ENVIO_MOVIMIENTO SET FECHA_IMAGEN = ?, FECHA_CARGA_IMAGEN = ?, CODIGO_GESTION = ? WHERE CODIGO_BARRAS = ? AND (CODIGO_GESTION = ? OR CODIGO_GESTION = ?) ");
                statementDB2UpdateEnvioMovimientoSinFechaGestion = conDB2.prepareStatement("UPDATE "+ SCHEMA +".ENVIO_MOVIMIENTO SET FECHA_CARGA_IMAGEN = ?, CODIGO_GESTION = ? WHERE CODIGO_BARRAS = ? AND (CODIGO_GESTION = ? OR CODIGO_GESTION = ?)");
                
                stmtUpdateReenvio = conDB2.prepareStatement("UPDATE "+ SCHEMA +".REENVIO SET ESTADO = ?, CODIGO_GESTION = ? WHERE CODIGO_BARRAS = ? ");
                
                Iterator iterator = imagenesConEnvio.iterator();

                while(iterator.hasNext()) 
                {
                    ImagenDto dto = (ImagenDto)iterator.next();

                    try
                    {
                        String rutaNueva = copiarImagenGuia(dto);                        
                        //String rutaNueva = "/PathPrueba";

                        if(rutaNueva != null)
                        {
                            try
                            {
                                int indice = 0; 
                                statementDB2UpdateEnvio.setObject(++indice, dto.getCodigoGestion());
                                statementDB2UpdateEnvio.setObject(++indice, rutaNueva);
                                statementDB2UpdateEnvio.setObject(++indice, new java.sql.Date(dto.getFechaProceso().getTime()));  
                                statementDB2UpdateEnvio.setObject(++indice, dto.getCodigoBarras());
                                statementDB2UpdateEnvio.executeUpdate();
                                
                                indice = 0;          
                                statementSQL.setObject(++indice, STATE_SUCCESS_COPY);
                                statementSQL.setObject(++indice, timestampAtMoment);
                                statementSQL.setObject(++indice, dto.getConsecutivo());  
                                statementSQL.executeUpdate();   

                                indice = 0;         
                                stmtUpdateReenvio.setObject(++indice, CODIGO_GESTION_REENVIO);
                                stmtUpdateReenvio.setObject(++indice, dto.getCodigoGestion());   
                                stmtUpdateReenvio.setObject(++indice, dto.getCodigoBarras());
                                stmtUpdateReenvio.executeUpdate();
                                
                                if(!dto.getCodigoUltimaGestion().equals(ENTREGA_NORMAL_DB2) && !dto.getCodigoUltimaGestion().equals(ENTREGA_BAJOPUERTA_DB2) )
                                {
                                    if( dto.getFechaGestion() != null )
                                    {
                                        indice = 0;                                 
                                        statementDB2InsertEnvioMovimiento.setObject(++indice, dto.getCodigoBarras());
                                        statementDB2InsertEnvioMovimiento.setObject(++indice, dto.getCodigoGestion());
                                        statementDB2InsertEnvioMovimiento.setObject(++indice, dateAtMoment);
                                        statementDB2InsertEnvioMovimiento.setObject(++indice, new java.sql.Date(dto.getFechaGestion().getTime()));   
                                        statementDB2InsertEnvioMovimiento.setObject(++indice, new java.sql.Date(dto.getFechaProceso().getTime()));  
                                        statementDB2InsertEnvioMovimiento.executeUpdate();
                                        
                                        indice = 0; 
                                        statementDB2UpdateEnvioFecha.setObject(++indice, new java.sql.Date(dto.getFechaGestion().getTime()));
                                        statementDB2UpdateEnvioFecha.setObject(++indice, dto.getCodigoBarras());
                                        statementDB2UpdateEnvioFecha.executeUpdate();
                                    }
                                    else
                                    {
                                        indice = 0;                                 
                                        statementDB2InsertEnvioMovimientoSinFechaGestion.setObject(++indice, dto.getCodigoBarras());
                                        statementDB2InsertEnvioMovimientoSinFechaGestion.setObject(++indice, dto.getCodigoGestion());
                                        statementDB2InsertEnvioMovimientoSinFechaGestion.setObject(++indice, dateAtMoment);
                                        statementDB2InsertEnvioMovimientoSinFechaGestion.setObject(++indice, new java.sql.Date(dto.getFechaProceso().getTime()));  
                                        statementDB2InsertEnvioMovimientoSinFechaGestion.executeUpdate();                                  
                                    }
                                }
                                else
                                {
                                    if( dto.getFechaGestion() != null )
                                    {
                                        indice = 0;    
                                        statementDB2UpdateEnvioMovimiento.setObject(++indice, dto.getFechaGestion());   
                                        statementDB2UpdateEnvioMovimiento.setObject(++indice, dto.getFechaProceso());    
                                        statementDB2UpdateEnvioMovimiento.setObject(++indice, dto.getCodigoGestion());
                                        statementDB2UpdateEnvioMovimiento.setObject(++indice, dto.getCodigoBarras());                                        
                                        statementDB2UpdateEnvioMovimiento.setObject(++indice, ENTREGA_NORMAL_DB2);
                                        statementDB2UpdateEnvioMovimiento.setObject(++indice, ENTREGA_BAJOPUERTA_DB2);
                                        statementDB2UpdateEnvioMovimiento.executeUpdate();
                                        
                                        indice = 0; 
                                        statementDB2UpdateEnvioFecha.setObject(++indice, new java.sql.Date(dto.getFechaGestion().getTime()));
                                        statementDB2UpdateEnvioFecha.setObject(++indice, dto.getCodigoBarras());
                                        statementDB2UpdateEnvioFecha.executeUpdate();
                                    }
                                    else
                                    {
                                        indice = 0;    
                                        statementDB2UpdateEnvioMovimientoSinFechaGestion.setObject(++indice, dto.getFechaProceso());          
                                        statementDB2UpdateEnvioMovimientoSinFechaGestion.setObject(++indice, dto.getCodigoGestion());
                                        statementDB2UpdateEnvioMovimientoSinFechaGestion.setObject(++indice, dto.getCodigoBarras());                                        
                                        statementDB2UpdateEnvioMovimientoSinFechaGestion.setObject(++indice, ENTREGA_NORMAL_DB2);
                                        statementDB2UpdateEnvioMovimientoSinFechaGestion.setObject(++indice, ENTREGA_BAJOPUERTA_DB2);
                                        statementDB2UpdateEnvioMovimientoSinFechaGestion.executeUpdate();
                                    }                                        
                                }                              
                            }
                            catch (SQLException e) 
                            {
                                System.out.println("ImagenesPlusDAO: actualizarInfoEnvios: " + e.toString());
                                e.printStackTrace();
                            }
                            catch (Exception e) 
                            {
                                System.out.println("ImagenesPlusDAO: actualizarInfoEnvios: " + e.toString());
                                e.printStackTrace();
                            }                         
                        }
                    }
                    catch(CopiaImagenException ciex)
                    {
                        System.out.println("ImagenesPlusDAO: actualizarInfoEnvios: " + ciex.toString());
                        ciex.printStackTrace();
                    }
                }
            }
            catch (SQLException e) 
            {
                throw new DAOException("ImagenesPlusDAO: actualizarInfoEnvios: " + e.toString(), e);
            }
            catch (Exception e) 
            {
                throw new DAOException("ImagenesPlusDAO: actualizarInfoEnvios: " + e.toString(), e);
            }
            finally 
            {
                closeConnection(null, stmtUpdateReenvio);
                closeConnection(null, statementDB2UpdateEnvio);
                closeConnection(null, statementDB2UpdateEnvioFecha);
                                
                closeConnection(null, statementDB2UpdateEnvioMovimiento);                
                closeConnection(null, statementDB2UpdateEnvioMovimientoSinFechaGestion);
                
                closeConnection(null, statementDB2InsertEnvioMovimientoSinFechaGestion);
                closeConnection(conDB2, statementDB2InsertEnvioMovimiento); 
                
                closeConnection(conSQL, statementSQL);
            }
        }
    }
    
    public String copiarImagenGuia(ImagenDto dto) throws CopiaImagenException
    {
        String destinoImagenCopia = null;
        
        Calendar cal = Calendar.getInstance();
        String nombreCarpetaDestino = PATH_DESTINO + "FORMS" + SEPARATOR + cal.get(Calendar.YEAR)+ SEPARATOR + (cal.get(Calendar.MONTH) + 1) + SEPARATOR + cal.get(Calendar.DAY_OF_MONTH); 
             
        FileInputStream fileInputStreamOrigen = null;
        FileOutputStream fileOutputStreamDestino = null;
        FileChannel fileChannelOrigen = null;
        FileChannel fileChannelDestino = null;
        try
        {
            File carpetaDestinoFile = new File(nombreCarpetaDestino);
            if (!carpetaDestinoFile.exists()){ carpetaDestinoFile.mkdirs(); }
            
            File fileOrigen = new File(PATH_ORIGEN + dto.getRuta());
            fileInputStreamOrigen  = new FileInputStream(fileOrigen);
            
            destinoImagenCopia = nombreCarpetaDestino + File.separator + dto.getCodigoBarras() + EXTENSION;
            
            fileOutputStreamDestino = new FileOutputStream(destinoImagenCopia);
            fileChannelOrigen = fileInputStreamOrigen.getChannel();
            fileChannelDestino = fileOutputStreamDestino.getChannel();
            fileChannelOrigen.transferTo(0, fileChannelOrigen.size(), fileChannelDestino);
            
        }
        catch (FileNotFoundException e) {
            throw new CopiaImagenException("ImagenesPlusDAO:copiarImagenGuia: " + e.toString(), e);
        }
        catch (IOException e) {
            throw new CopiaImagenException("ImagenesPlusDAO:copiarImagenGuia: " + e.toString(), e);
        }
        catch (Exception e) 
        {
            throw new CopiaImagenException("ImagenesPlusDAO:copiarImagenGuia: " + e.toString(), e);
        }
        finally
        {
            cerraFlujosArchivos(fileInputStreamOrigen,fileOutputStreamDestino,fileChannelOrigen,fileChannelDestino);            
        }
        
        return destinoImagenCopia;
    }
    
    protected void cerraFlujosArchivos(FileInputStream fileInputStreamOrigen, FileOutputStream fileOutputStreamDestino, FileChannel fileChannelOrigen, FileChannel fileChannelDestino) throws CopiaImagenException
    {
        try
        {
            if(fileInputStreamOrigen != null) { fileInputStreamOrigen.close(); }
            if(fileOutputStreamDestino != null) { fileOutputStreamDestino.close(); }
            if(fileChannelOrigen != null) { fileChannelOrigen.close(); }
            if(fileChannelDestino != null) { fileChannelDestino.close(); }
        }
        catch(IOException e)
        {
            throw new CopiaImagenException("ImagenesPlusDAO:cerraFlujosArchivos: Error cerrando los flujos " + e.toString(), e);
        }
        catch (Exception e) 
        {
            throw new CopiaImagenException("ImagenesPlusDAO:cerraFlujosArchivos: Error cerrando los flujos " + e.toString(), e);
        }
    }
}
